/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include <ppl.h>
#include <windows.h>

#include "ui菜单.h"

#include "UI/布局.h"
#include "UI/ui绘制模板.h"





static S_UI创建环境* g_UIctx;


static bool g是否打开了菜单 = false;
C_菜单* C_菜单::m_当前打开菜单 = 0;

//static ui_绘制模板_画预设图形 m_弹出菜单背景绘制;
//DEF_图标绘制ID(菜单)

float32 g菜单项圆角 = 4;
float32 g菜单文件间隔 = 1;
vec2 g菜单边界宽度 = { 20, 20 };
float32 g菜单顶部偏移 = 10;
static float32 g图标宽度 = 30;







static bool g上层鼠标以移出 = false;
static int32 g当前焦点部件层 = -1;

static HANDLE hThread = 0;



DWORD WINAPI f_菜单关闭(LPVOID pParam) {
	int i = 0;

	Sleep(600);
	if (g上层鼠标以移出) {
		g是否打开了菜单 = false;
		f_widget_顶层窗口_pop(0);
	}
	
	return 0;
}






static bool on_横向鼠标进入(C_Widget* self, const S_鼠标& 轮值) {
	C_菜单* menu = dynamic_cast<C_菜单*>(self);
	//C_菜单* pMenu = dynamic_cast<C_菜单*>(menu->m_父部件);
	g上层鼠标以移出 = false;

	uint8 topNum = f_widget_getTopNum();
	if (menu->m_layer == 0 && topNum > 0) {
		g是否打开了菜单 = true;
		f_widget_顶层窗口_pop(1);
	}
	else if (menu->m_layer < topNum) {
		g是否打开了菜单 = true;
		f_widget_顶层窗口_pop(menu->m_layer + 1);
	}
	
	g当前焦点部件层 = menu->m_layer;
	//std::cout << "进入空事件:" << ((C_Widget*)w)->m_Name << std::endl;
	return false;
}

static bool on_横向鼠标移出(C_Widget* self, const S_鼠标& 轮值) {
	C_菜单* menu = dynamic_cast<C_菜单*>(self);
	uint8 topNum = f_widget_getTopNum();
	
	g上层鼠标以移出 = true;
	//创建线程
	hThread = CreateThread(NULL, 0, f_菜单关闭, NULL, 0, NULL);
	return false;
}




static void f_draw横向菜单(C_Widget* self, S_2D画布* 画布) {
	C_菜单* menu = dynamic_cast<C_菜单*>(self);

	menu->m_背景绘制.m_属性 = f_vg_gen属性(画布);
	S_凸边图元 图元 = {};
	图元.属性 = f_vg_get属性指针(画布, menu->m_背景绘制.m_属性);
	//图元.属性 = f_vg_get属性(画布, menu->m_背景绘制.m_属性);
	menu->m_背景绘制.f_Draw(画布, 图元, E_笔刷类型::e_单色填充);
}

static void f_draw横向菜单布局(C_Widget* self, C_Widget** w, uint32 num) {
	vec2 pos = { float32(self->m_间隔宽度 + 10), float32(self->m_间隔宽度) };
	vec2 h{(self->m_Size.y - g菜单项圆角 * 2) * 0.8f };
	//h.y = (self->m_Size.y - h.x) * 0.5;
	h.y = self->m_Size.y - self->m_间隔宽度*2;

	for (uint32 i = 0; i < num; ++i) {
		w[i]->f_setPos(pos);
		w[i]->f_setH(h.y);

		pos.x += w[i]->m_Size.x + 3;
	}
}

static void f_set横向菜单变换修改(C_Widget* self) {
	C_菜单* menu = dynamic_cast<C_菜单*>(self);

	uint32 菜单项数量 = self->m_子组件.size();
	auto* sw = self->m_子组件.data();
	//return;
	menu->m_背景绘制.f_alloc(1);

	mat3X2 mat;
	mat.row0 = self->m_Pos;
	mat.row1 = self->m_Size;
	mat.row2 = { 1, 0 };
	//menu->m_背景绘制.f_GPU参数修改(0, mat, S_UI主题::uic_菜单条背景, S_Widget预设图元::m_矩形);
	menu->m_背景绘制.f_set单色填充(0, mat, S_UI主题::uic_菜单条背景, S_Widget预设图元::m_矩形);
	
}















static void f_draw纵向菜单(C_Widget* self, S_2D画布* 画布) {
	C_菜单* menu = dynamic_cast<C_菜单*>(self);

	menu->m_背景绘制.m_属性 = f_vg_gen属性(画布);
	//menu->m_背景绘制.f_Draw文本(画布, menu->m_背景绘制.m_属性);
	S_凸边图元 图元 = {};
	图元.属性 = f_vg_get属性指针(画布, menu->m_背景绘制.m_属性);
	menu->m_背景绘制.f_Draw(画布, 图元, E_笔刷类型::e_单色填充);

	图元 = {};
	图元.属性 = f_vg_get属性指针(画布, menu->m_背景绘制.m_属性);
	menu->m_分隔线绘制.f_Draw(画布, 图元, E_笔刷类型::e_单色描边);
}

static void f_draw纵向菜单布局(C_Widget* self, C_Widget** w, uint32 num) {
	C_菜单* menu = dynamic_cast<C_菜单*>((C_Widget*)self);

	auto& font = f_surface_get字体库(*menu->m_UIctx, S_UI主题::ui_默认字体);

	int32 字符串总数量 = 0;
	
	float32 maxWidth = 30;
	float32 maxHeigth = g菜单顶部偏移;
	for (int32 i = 0; i < num; ++i) {
		C_菜单项* item = dynamic_cast<C_菜单项*>(w[i]);
		if (item) {
			maxWidth = DEF_Max(maxWidth, f_surface_get字符串宽度(font, item->f_getTitle(), g菜单文件间隔));
		}

		maxHeigth + 20;
	}
	maxWidth += g图标宽度*2;
	
	vec2 size;/* = {
		maxWidth + g菜单边界宽度.x * 2, 
		f_VBOX固定布局(maxWidth, w, num, {g菜单边界宽度.x, g菜单顶部偏移})
	};*/
	vec2 pos = {g菜单边界宽度.x, g菜单顶部偏移};
	for (uint32 i = 0; i < num; ++i) {
		w[i]->f_setPos(pos);
		w[i]->f_setW(maxWidth);

		pos.y += w[i]->m_Size.y;
	}
	size.x = maxWidth + g菜单边界宽度.x * 2;
	size.y = pos.y + g菜单顶部偏移;
	
	self->f_setSize(size);
	f_widget_单个部件裁剪(self, { 0, 0, self->m_Pos.x + size.x, self->m_Pos.y + size.y }, { 0,0 });
}

static void f_set纵向菜单变换修改(C_Widget* self) {
	C_菜单* menu = dynamic_cast<C_菜单*>(self);

	auto e = self->f_get更新部件();

	menu->m_背景绘制.f_alloc(1);
	mat3X2 mat;
	mat.row0 = { g菜单边界宽度.x, 0 };
	mat.row1 = { self->m_Size.x - g菜单边界宽度.x * 2, self->m_Size.y };
	mat.row2 = { S_UI主题::ui_面板圆角半径*2, 0 };
	menu->m_背景绘制.f_set单色填充(0, mat, S_UI主题::uic_菜单背景, S_Widget预设图元::m_圆角矩形);
	
	uint32 间隔数量 = 0;
	for (uint32 i = 0; i < e.m_Num; ++i) {
		if (((C_菜单项*)e.m_W[i])->m_标题.empty()) {
			++间隔数量;
		}
	}

	S_LineProp 线属性 = {0, f_PackData4X8(S_UI主题::uic_页面标签), f_PackData4X8(S_UI主题::uic_页面标签)};
	menu->m_分隔线绘制.f_alloc(间隔数量);
	间隔数量 = 0;
	for (uint32 i = 0; i < e.m_Num; ++i) {
		if (((C_菜单项*)e.m_W[i])->m_标题.empty()) {
			mat.row0 = e.m_W[i]->m_Pos + 2;
			mat.row1 = e.m_W[i]->m_Size - 4;
			menu->m_分隔线绘制.f_set单色线(间隔数量, mat, 线属性, S_Widget预设图元::m_横线, 2.0);
			++间隔数量;
		}
	}
}



C_菜单::C_菜单(E_方向 dir, S_UI创建环境& ctx) : C_Widget(&ctx), m_排列方向(dir), m_layer(0) {
	f_setMinSize({ 20, 24 });
	m_TypeName = "C_菜单";
	//m_文本对象 = (S_2D文本对象*)malloc(sizeof(S_2D文本对象));
	//*(m_文本对象) = {0, 0};

	g_UIctx = &ctx;
	if (dir == E_方向::e_横向) {
		mf_布局Fun = f_draw横向菜单布局;
		mf_DrawFun = f_draw横向菜单;
		mf_变换修改 = f_set横向菜单变换修改;
	}
	else if (dir == E_方向::e_纵向) {
		mf_布局Fun = f_draw纵向菜单布局;
		mf_DrawFun = f_draw纵向菜单;
		mf_变换修改 = f_set纵向菜单变换修改;
	}

	mf_鼠标进入 = on_横向鼠标进入;
	mf_鼠标离开 = on_横向鼠标移出;
}

C_菜单::~C_菜单() {
}

void C_菜单::f_打开(const vec2& pos, const bool 记忆) {
	vec2 偏移 = pos;
	偏移.x -= g菜单边界宽度.x;

	f_setPos(偏移);

	m_GlobalLoc = 偏移;
	g是否打开了菜单 = true;
}

void C_菜单::f_关闭() {
	
}

C_菜单项* C_菜单::f_添加项(const std::wstring txt, std::string ico) {
	const auto& font = f_surface_get字体库(*m_UIctx, S_UI主题::ui_默认字体);

	C_菜单项* obj = new C_菜单项(*m_UIctx, txt, ico, font.m_字号 * 1.5 * m_UIctx->m_DPI);

	obj->m_实例ID = this->f_get子部件数量();
	f_添加子组件(obj);
	
	return obj;
}

void C_菜单::f_移除项(C_菜单项 * itme) {
	
}


void on_鼠标退出() {
	
}

void C_菜单::f_设置项冻结(uint32 id, bool y) {
	
}






static void on_draw菜单项(C_Widget* self, S_2D画布* 画布) {
	C_菜单项* item = dynamic_cast<C_菜单项*>(self);
	item->m_背景绘制.m_属性 = f_vg_gen属性(画布);

	S_凸边图元 图元 = {};
	图元.属性 = f_vg_get属性指针(画布, item->m_背景绘制.m_属性);
	item->m_背景绘制.f_Draw(画布, 图元, E_笔刷类型::e_单色填充);
	
	auto 字体 = f_surface_get字体(*self->m_UIctx, S_UI主题::ui_默认字体);
	item->m_字符绘制.f_Draw(画布, &字体, item->m_背景绘制.m_属性);
	item->m_图标绘制.f_Draw单色(画布, item->m_背景绘制.m_属性, S_UI主题::ui_默认图标);
	
}


static void on_菜单项变换修改(C_Widget* self) {
	C_菜单项* item = dynamic_cast<C_菜单项*>(self);
	C_菜单* menu = dynamic_cast<C_菜单*>(item->m_父部件);
	if (!menu) return;
	
	item->m_背景绘制.f_alloc(1);
	mat3X2 mat;
	mat.row0 = {};
	mat.row1 = { self->m_Size.x, self->m_Size.y };
	mat.row2 = { S_UI主题::ui_面板圆角半径, 0 };
	item->m_背景绘制.f_set单色填充(0, mat, { 0,0,0,0 }, S_Widget预设图元::m_圆角矩形);
	
	//return;
	item->m_字符绘制.f_alloc(1, 128);
	item->m_图标绘制.f_alloc(1);
	auto txt = item->f_getTitle();
	if (menu->m_排列方向 == E_方向::e_横向) {
		item->m_字符绘制.f_居中绘制文本({ mat.row0, mat.row1 }, S_UI主题::uic_文字颜色, 0, txt);
		item->m_图标绘制.f_set("", 0, mat, S_UI主题::uic_文字颜色);
	}
	else {
		mat.row0.x = g图标宽度;
		item->m_字符绘制.f_设置文本({ mat.row0, mat.row1 }, S_UI主题::uic_文字颜色, 0, txt);

		mat.row0.x = self->m_Size.y * 0.5 + 5;
		mat.row0.y = self->m_Size.y * 0.5;
		mat.row1.x = self->m_Size.y * 0.8;
		
		item->m_图标绘制.f_set(item->m_图标, 0, mat, S_UI主题::uic_文字颜色);
	}
	
}

static bool on_菜单项鼠标进入事件(C_Widget* self, const S_鼠标& 轮值) {
	C_菜单项* item = dynamic_cast<C_菜单项*>(self);
	
	if (item) {
		mat3X2 mat = {};

		item->m_背景绘制.f_alloc(1);
		mat.row0 = {};
		mat.row1 = self->m_Size;
		mat.row2 = { S_UI主题::ui_面板圆角半径, 0 };
		//item->m_背景绘制.f_GPU参数修改(0, mat, S_UI主题::uic_菜单焦点色, S_Widget预设图元::m_圆角矩形);
		item->m_背景绘制.f_set单色填充(0, mat, S_UI主题::uic_菜单焦点色, S_Widget预设图元::m_圆角矩形);
		
		//item->m_字符绘制.f_Begin(1, 128);
		C_菜单* menu = dynamic_cast<C_菜单*>(item->m_父部件);
		if (!menu) return false;
		
		
		mat.row2 = { 1, 0 };
		if (menu->m_排列方向 == E_方向::e_纵向) {
			//=================== 纵向菜单焦点变换属性 ===================
			
			if (item->m_父部件->m_画布->m_是否重绘 == false) {
				//f_vg_set变换(item->m_父部件->m_画布, g菜单项绘制变换ID, 0, mat);
				//f_vg_set实例数量(item->m_父部件->m_画布, g纵向菜单项元素ID, 1);
			}
		}
		else {
			mat.row0 = item->m_Pos;
			mat.row1 = item->m_Size;

			//===================== 在横向菜单中自动打开纵向菜单 ==================
			if (menu->m_layer == 0 && g是否打开了菜单) {
				if (item->ui_子菜单) {
					f_widget_顶层窗口_push(item->ui_子菜单, menu->m_layer);

					item->ui_子菜单->f_打开({ item->m_裁剪大小.x, item->m_裁剪大小.w });
				}
			}
		}
	}
	//std::cout << "**********************菜单项进入空事件:" << ((C_Widget*)w)->m_Name << std::endl;
	return false;
}
static bool on_菜单项鼠标移除事件(C_Widget* self, const S_鼠标& 轮值) {
	C_菜单项* item = dynamic_cast<C_菜单项*>(self);
	//f_vg_set实例数量(item->m_父部件->m_画布, g菜单项元素ID, 0);
	C_菜单* menu = dynamic_cast<C_菜单*>(item->m_父部件);
	if (!menu) return false;

	item->m_背景绘制.f_alloc(1);
	mat3X2 mat;
	mat.row0 = {};
	mat.row1 = self->m_Size;
	mat.row2 = { S_UI主题::ui_面板圆角半径, 0 };
	item->m_背景绘制.f_set单色填充(0, mat, {}, S_Widget预设图元::m_圆角矩形);
	
	//std::cout << "**********************菜单项移除空事件" << ((C_Widget*)w)->m_Name << std::endl;
	return false;
}




bool on_菜单项点击事件(C_Widget* self, const E_鼠标按钮& 按钮) {
	C_菜单项* selfItem = dynamic_cast<C_菜单项*>(self);
	C_菜单* menu = dynamic_cast<C_菜单*>(selfItem->m_父部件);

	if (selfItem->ui_子菜单) {
		//打开子菜单
		f_widget_顶层窗口_pop(menu->m_layer);
		f_widget_弹出顶层窗口(selfItem->ui_子菜单);
		
		if (menu->m_排列方向 == E_方向::e_纵向) {
			vec2 pos = { selfItem->m_裁剪大小.z, selfItem->m_裁剪大小.y - g菜单顶部偏移 };
			pos = f_widget_弹出窗口坐标矫正(selfItem->ui_子菜单, pos);
			//vec2 pos = f_菜单子项坐标矫正(selfItem);
			selfItem->ui_子菜单->f_打开(pos);
		}
		else {
			selfItem->ui_子菜单->f_打开({ selfItem->m_裁剪大小.x, selfItem->m_裁剪大小.w });
		}
		
	} else if(selfItem->mf_菜单事件) {
		//执行菜单事件
		selfItem->mf_菜单事件(selfItem, selfItem->f_getTitle(), selfItem->m_实例ID);

		g是否打开了菜单 = false;
		f_widget_顶层窗口_pop(0);
	}
	
	return true;
}


C_菜单项::C_菜单项(S_UI创建环境& ctx, const std::wstring txt, const std::string& ico, float32 菜单厚度) : C_Widget(&ctx), m_标题(txt), m_图标(ico) {
	m_TypeName = "C_菜单项";
	ui_子菜单 = nullptr;

	const auto& font = f_surface_get字体库(*m_UIctx, S_UI主题::ui_默认字体);
	if (m_标题.empty()) {
		f_setMinSize({ m_UIctx->m_DPI*35.0f, 6 });
	}
	else {
		f_setMinSize({ m_UIctx->m_DPI*35.0f, font.m_字号 * 1.8f * m_UIctx->m_DPI });
	}
	

	mf_鼠标进入 = on_菜单项鼠标进入事件;
	mf_鼠标离开 = on_菜单项鼠标移除事件;

	mf_鼠标按键点击 = on_菜单项点击事件;
	mf_菜单事件 = 0;

	mf_DrawFun = on_draw菜单项;
	mf_变换修改 = on_菜单项变换修改;
}




C_菜单* C_菜单项::f_添加子菜单(uint32 layer, S_UI创建环境& ctx) {
	ui_子菜单 = new C_菜单(E_方向::e_纵向, ctx);
	ui_子菜单->m_layer = layer;

	return ui_子菜单;
}


void C_菜单项::f_关闭菜单链(C_Widget* w) {
	if (w) {
		
	}
}


















vec2 f_菜单子项坐标矫正(C_菜单项* 项) {
	auto e = 项->ui_子菜单->f_get更新部件();
	项->ui_子菜单->mf_布局Fun(项->ui_子菜单, e.m_W, e.m_Num);

	vec2 当前菜单大小 = 项->ui_子菜单->m_Size;
	vec4 窗口大小 = f_widget_get当前窗口矩形();
	vec2 pos = { 项->m_裁剪大小.z, 项->m_裁剪大小.y - g菜单顶部偏移 };
	
	if (pos.x + 当前菜单大小.x >= 窗口大小.z) {
		pos.x = (项->m_裁剪大小.x - 当前菜单大小.x + g菜单边界宽度.x*2);
	} 

	if (pos.y + 当前菜单大小.y >= 窗口大小.w) {
		pos.y = (窗口大小.w - 当前菜单大小.y + g菜单边界宽度.x*2);
	}

	return pos;
}

vec2 f_菜单坐标矫正(C_菜单* 菜单, vec2 pos) {
	auto e = 菜单->f_get更新部件();
	菜单->mf_布局Fun(菜单, e.m_W, e.m_Num);

	vec4 当前菜单大小 = 菜单->m_裁剪大小;
	vec4 窗口大小 = f_widget_get当前窗口矩形();

	if (pos.x + 菜单->m_Size.x - g菜单边界宽度.x >= 窗口大小.z) {
		pos.x = 窗口大小.z - 菜单->m_Size.x + g菜单边界宽度.x*2;
	}

	if (pos.y + 菜单->m_Size.y - g菜单边界宽度.x >= 窗口大小.w) {
		pos.y = 窗口大小.w - 菜单->m_Size.y + g菜单边界宽度.x * 2;
	}

	return pos;
}


















/*typedef struct {
	S_2D文本对象	m_文本对象;
	S_2D画布* m_菜单画布;
}S_2D画布文本对象;
static std::vector<S_2D画布文本对象>	g顶层菜单画布;

void f_顶层菜单画布构建(C_菜单* self, uint32 layer, S_UI创建环境& ctx) {
	if (layer > g顶层菜单画布.size()) {
		g顶层菜单画布.push_back({ {}, f_创建2D面对象(0, ctx.m_Ctx) });

		self->m_文本对象 = &(g顶层菜单画布.back().m_文本对象);
		self->m_画布 = g顶层菜单画布.back().m_菜单画布;
		self->m_画布->m_调色板 = &(ctx.m_Mat);

	}
	else {
		self->m_画布 = g顶层菜单画布[layer - 1].m_菜单画布;
		self->m_文本对象 = &(g顶层菜单画布[layer - 1].m_文本对象);
	}
}*/









